rm(list = ls())
Mobile Legends: Bang Bang is a MOBA game (Multiplayer online battle arena) for mobile devices with Android and iOS developed by Shanghai Moonton. The game was originally released in Asia on 11th of June 2016.
In the game there are 2 opposing teams consisting of 5 players each. Players choose a character they will play with before game starts. As for now there are around 90 champions (character) to choose from. Each character is different and may be used for different purposes depending on their skills and abillities. In that way one can distinguish mages, assasins and some more types of champions. Main task is to destroy enemies’ defence towers resulting in concquering their base (yup, it’s very boring but somehow very popular).
The game was getting more and more attention in Poland for a couple of years now. The graph below presents interest over time for google query “Mobile Legends” and “MOBA” in Poland. As you can see around 2017 there was a hugh increase in popularity of the game while interest in MOBA games in general was falling down gradually in past 5 years. However in March and April 2020 they experienced a rapid renaissance. We can probably associate it with a lockdown caused by COVID-19 outbreak.
As stated above there are several types of characters in that game so we will try to label them based on their characteristics. In order to do so we are going to implement Principal Component Analysis to reduce dimentionallity and then k-means method to cluster them. Although the labels are known such an analysis may be helpful for maintaining characters’ skill sets in a balance way.
First of all let’s have a look on how our data looks like. In the table below you can find all characters in alphabetical order.
One important remark is although the list below present all playable characters right now we are going to consider it as sample since the characters’ set is being constantly updated with new characters - in that way statistical inference can be justified.
| Id | Hero | Movement speed | Magic Resistance | Mana | HP Regen Rate | Physical Attack | Armor | Health points | Attack speed | Mana regen rate | Role | Special |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Akai | 260 | 10 | 422 | 42 | 115 | 24 | 2769 | 0.8500 | 12 | TK | Initiator |
| 2 | Aldous | 260 | 10 | 405 | 49 | 129 | 21 | 2718 | 0.8360 | 18 | FT | Push |
| 3 | Alice | 240 | 10 | 493 | 36 | 114 | 21 | 2573 | 0.8000 | 18 | MG | Charge |
| 4 | Alpha | 260 | 10 | 453 | 39 | 121 | 20 | 2646 | 0.9160 | 31 | FT | Charge |
| 5 | Alucard | 260 | 10 | 0 | 39 | 123 | 21 | 2821 | 0.9000 | 0 | FT | Charge |
| 6 | Angela | 240 | 10 | 515 | 34 | 115 | 15 | 2421 | 0.7920 | 18 | SP | Regen |
| 7 | Argus | 260 | 10 | 0 | 40 | 124 | 21 | 2628 | 0.9160 | 0 | FT | Charge |
| 8 | Aurora | 245 | 10 | 750 | 34 | 110 | 17 | 2501 | 0.8000 | 23 | MG | Crowrd Control |
| 9 | Badang | 255 | 10 | 0 | 40 | 119 | 23 | 2708 | 0.9080 | 0 | FT | Charge |
| 10 | Balmond | 260 | 10 | 0 | 47 | 119 | 25 | 2836 | 0.8500 | 0 | FT | Charge |
| 11 | Bane | 260 | 10 | 433 | 42 | 117 | 23 | 2559 | 0.8500 | 12 | FT | Push |
| 12 | Belerick | 250 | 10 | 450 | 42 | 110 | 15 | 2719 | 0.8100 | 12 | TK | Regen |
| 13 | Bruno | 240 | 10 | 439 | 30 | 128 | 17 | 2522 | 0.8500 | 15 | MM | Reap |
| 14 | Change | 240 | 10 | 505 | 34 | 115 | 16 | 1301 | 0.8080 | 21 | MG | Reap |
| 15 | Chou | 260 | 10 | 0 | 39 | 121 | 23 | 2708 | 0.8840 | 0 | FT | Charge |
| 16 | Claude | 240 | 10 | 450 | 40 | 97 | 14 | 2370 | 0.8260 | 16 | MM | Reap |
| 17 | Clint | 240 | 10 | 450 | 36 | 115 | 20 | 2530 | 0.8420 | 15 | MM | Burst |
| 18 | Cyclops | 240 | 10 | 500 | 38 | 112 | 18 | 2521 | 0.8000 | 20 | MG | Damage |
| 19 | Diggie | 250 | 10 | 490 | 36 | 115 | 16 | 2351 | 0.8000 | 20 | SP | Crowrd Control |
| 20 | Dyrroth | 265 | 10 | 0 | 41 | 117 | 22 | 2758 | 0.9160 | 0 | FT | Charge |
| 21 | Esmeralda | 240 | 10 | 502 | 36 | 114 | 21 | 2573 | 0.8000 | 20 | MG | Regen |
| 22 | Estes | 240 | 10 | 545 | 36 | 120 | 13 | 2221 | 0.8000 | 18 | SP | Regen |
| 23 | Eudora | 250 | 10 | 468 | 38 | 112 | 19 | 2524 | 0.8000 | 16 | MG | Burst |
| 24 | Fanny | 265 | 10 | 0 | 33 | 126 | 19 | 2526 | 0.8940 | 0 | ASS | Charge |
| 25 | Faramis | 245 | 10 | 500 | 34 | 118 | 20 | 2543 | 0.7840 | 19 | SP | Initiator |
| 26 | Franco | 260 | 10 | 440 | 46 | 116 | 25 | 2709 | 0.8260 | 10 | TK | Initiator |
| 27 | Freya | 260 | 10 | 462 | 49 | 109 | 22 | 2801 | 0.8760 | 14 | FT | Charge |
| 28 | Gatotkaca | 260 | 10 | 420 | 42 | 120 | 20 | 2629 | 0.8180 | 12 | TK | Crowrd Control |
| 29 | Gord | 240 | 10 | 570 | 32 | 110 | 13 | 2478 | 0.7720 | 25 | MG | Damage |
| 30 | Granger | 240 | 10 | 0 | 27 | 110 | 15 | 2490 | 0.8180 | 0 | MM | Reap |
| 31 | Grock | 260 | 10 | 430 | 42 | 135 | 21 | 2819 | 0.8100 | 12 | TK | initiator |
| 32 | Guineveree | 260 | 10 | 0 | 39 | 126 | 18 | 2528 | 0.9180 | 0 | MG | Charge |
| 33 | Gusion | 260 | 10 | 460 | 39 | 119 | 18 | 2578 | 0.8920 | 16 | ASS | Charge |
| 34 | Hanabi | 245 | 10 | 390 | 30 | 105 | 17 | 2510 | 0.8500 | 15 | MM | Regen |
| 35 | Hanzo | 260 | 10 | 0 | 35 | 118 | 17 | 2594 | 0.8700 | 0 | ASS | Reap |
| 36 | Harith | 240 | 10 | 490 | 36 | 114 | 19 | 2701 | 0.8400 | 18 | MG | Charge |
| 37 | Harley | 240 | 10 | 490 | 36 | 114 | 19 | 2501 | 0.8480 | 18 | MG | Burst |
| 38 | Hayabusa | 260 | 10 | 0 | 37 | 117 | 17 | 2629 | 0.8540 | 0 | ASS | Charge |
| 39 | Helcurt | 255 | 10 | 440 | 35 | 121 | 17 | 2599 | 0.8700 | 16 | ASS | Charge |
| 40 | Hilda | 260 | 10 | 0 | 42 | 123 | 24 | 2789 | 0.8420 | 0 | FT | Regen |
| 41 | Hylos | 260 | 10 | 430 | 92 | 105 | 17 | 3309 | 0.8260 | 12 | TK | Regen |
| 42 | Irithel | 260 | 10 | 438 | 35 | 118 | 17 | 2540 | 0.8260 | 15 | MM | Reap |
| 43 | Jawhead | 255 | 10 | 430 | 39 | 119 | 24 | 2778 | 0.9000 | 16 | FT | Charge |
| 44 | Johnson | 255 | 10 | 0 | 42 | 112 | 27 | 2809 | 0.8260 | 12 | TK | Crowrd Control |
| 45 | Kadita | 240 | 10 | 495 | 36 | 105 | 18 | 2491 | 0.8000 | 18 | MG | Burst |
| 46 | Kagura | 240 | 10 | 519 | 35 | 118 | 19 | 2556 | 0.8160 | 21 | MG | Damage |
| 47 | Kaja | 270 | 10 | 400 | 52 | 120 | 16 | 2609 | 0.8420 | 12 | SP | Initiator |
| 48 | Karina | 260 | 10 | 431 | 29 | 121 | 20 | 2633 | 0.9000 | 16 | ASS | Charge |
| 49 | Karrie | 240 | 10 | 440 | 40 | 120 | 17 | 2578 | 0.8396 | 15 | MM | Reap |
| 50 | Khufra | 255 | 10 | 460 | 47 | 117 | 19 | 2859 | 0.7860 | 15 | TK | Crowrd Control |
| 51 | Kimmy | 245 | 10 | 100 | 40 | 104 | 22 | 2450 | 0.8260 | 0 | MM | Damage |
| 52 | Lancelot | 260 | 10 | 450 | 35 | 124 | 16 | 2549 | 0.8700 | 16 | ASS | Charge |
| 53 | Lapu - Lapu | 260 | 10 | 0 | 35 | 119 | 21 | 2628 | 0.9000 | 16 | FT | Charge |
| 54 | Layla | 240 | 10 | 424 | 27 | 130 | 15 | 2500 | 0.8500 | 14 | MM | Reap |
| 55 | Leomord | 240 | 10 | 0 | 35 | 126 | 21 | 2738 | 0.8440 | 0 | FT | Push |
| 56 | Lesley | 240 | 10 | 0 | 36 | 131 | 14 | 2490 | 0.8260 | 0 | MM | Reap |
| 57 | Lolita | 260 | 10 | 480 | 48 | 115 | 27 | 2679 | 0.7860 | 12 | TK | Crowrd Control |
| 58 | Lunox | 250 | 10 | 540 | 34 | 115 | 15 | 2521 | 0.8080 | 23 | MG | Damage |
| 59 | Martis | 260 | 10 | 405 | 35 | 128 | 25 | 2738 | 0.8680 | 16 | FT | Reap |
| 60 | Minotaur | 260 | 10 | 0 | 44 | 123 | 18 | 2709 | 0.7300 | 0 | TK | Crowrd Control |
| 61 | Minsitthar | 260 | 10 | 380 | 37 | 121 | 23 | 2698 | 0.8520 | 16 | FT | Initiator |
| 62 | Miya | 240 | 10 | 445 | 30 | 129 | 17 | 2524 | 0.8500 | 15 | MM | Reap |
| 63 | Moscov | 240 | 10 | 420 | 32 | 125 | 16 | 2455 | 0.8140 | 15 | MM | Push |
| 64 | Nana | 250 | 10 | 510 | 34 | 115 | 17 | 2501 | 0.8640 | 18 | SP | Poke |
| 65 | Natalia | 260 | 10 | 486 | 35 | 121 | 18 | 2589 | 0.8860 | 18 | ASS | Charge |
| 66 | Odette | 240 | 10 | 495 | 34 | 105 | 18 | 2491 | 0.8000 | 23 | MG | Burst |
| 67 | Pharsa | 240 | 10 | 490 | 34 | 109 | 15 | 2421 | 0.7904 | 18 | MG | Damage |
| 68 | Rafaela | 245 | 10 | 545 | 36 | 117 | 15 | 2441 | 0.7920 | 23 | SP | Regen |
| 69 | Roger | 240 | 10 | 450 | 36 | 128 | 22 | 2730 | 0.8420 | 15 | FT | Reap |
| 70 | Ruby | 260 | 10 | 430 | 30 | 114 | 23 | 2859 | 0.8580 | 14 | FT | Crowrd Control |
| 71 | Saber | 260 | 10 | 443 | 35 | 118 | 17 | 2599 | 0.8700 | 16 | ASS | Charge |
| 72 | Selena | 240 | 10 | 490 | 34 | 110 | 15 | 2401 | 0.8040 | 18 | ASS | Reap |
| 73 | Sun | 260 | 10 | 400 | 41 | 114 | 23 | 2758 | 0.9160 | 16 | FT | Charge |
| 74 | Terizla | 255 | 10 | 430 | 54 | 129 | 19 | 2728 | 0.8000 | 21 | FT | Damage |
| 75 | Thamuz | 250 | 10 | 0 | 37 | 107 | 22 | 2758 | 0.8440 | 0 | FT | Reap |
| 76 | Tigreal | 260 | 10 | 450 | 42 | 112 | 25 | 2890 | 0.8260 | 12 | TK | Crowrd Control |
| 77 | Uranus | 260 | 10 | 455 | 32 | 115 | 20 | 2489 | 0.8340 | 12 | TK | Regen |
| 78 | Vale | 250 | 10 | 490 | 34 | 115 | 15 | 2401 | 0.8000 | 21 | MG | Crowrd Control |
| 79 | Valir | 245 | 10 | 495 | 34 | 105 | 18 | 2516 | 0.8000 | 18 | MG | Burst |
| 80 | Vexana | 245 | 10 | 490 | 38 | 112 | 17 | 2481 | 0.8000 | 20 | MG | Poke |
| 81 | Yi Sun-Shin | 250 | 10 | 438 | 36 | 124 | 18 | 2520 | 0.8580 | 15 | MM | Reap |
| 82 | Zhask | 240 | 10 | 490 | 34 | 107 | 15 | 2401 | 0.8000 | 20 | MG | Push |
| 83 | Zilong | 265 | 10 | 405 | 35 | 123 | 25 | 2689 | 0.9640 | 16 | FT | Charge |
One important thing we should be interested in is the variability of champions characteristics. Below you can see the coefficient of variation (in %).
| Movement speed | Magic Resistance | Mana | HP Regen Rate | Physical Attack | Armor | Health points | Attack speed | Mana regen rate |
|---|---|---|---|---|---|---|---|---|
| 3.68 | 0 | 55.7 | 20.9 | 6.19 | 17.79 | 8.22 | 5.02 | 56.95 |
The variabiliy of mana and mana regeneration exeeds 50% whereas for health points regeneration and armor it’s about 20%. We will have to check the data for outliers as those values might be inflated for instance just by a single observation. Rest of the variables vary just a bit (under 10%). The value for magic resistance is constant for every character so we are going to drop that variable in further analysis.
Now let’s look for some possible relationships and check distributions of the variables.
We can see some relationships - f.e. mana vs. mana regeneration and health points vs. armor and many more - we are going to investigate them soon.
There are some outliers - note a champion whose health point regeneration ability is almost 3 times more powerful than the mean for the sample. We can also see a champion whose health points ability is about 2 times weaker than the average. Let’s find out who are those people.
## Warning: Unknown or uninitialised column: `labels`.
| 41 | Hylos | 260 | 430 | 92 | 105 | 17 | 3.309 | 0.826 | 12 | TK | Regen |
| 14 | Change | 240 | 505 | 34 | 115 | 16 | 1.301 | 0.808 | 21 | MG | Reap |
For the sake of analysis we are going to remove both of them from our “sample”.
Density functions for variables like movement speed, mana and mana regenerations seem to be bimodal - it is clear sign there are some subpopulations in our “sample” so it is reasonable to conduct cluster analysis.
We can check the correlations and their significance - just for fun since Simson paradox might be present.
Firstly let’s calculate prinipal components using standarized data.
As scree plot would not tell us much we should choose the number of compontents based on eigenvalue thumb rule. Each of three top components has eigenvalue > 1, i.e. “contains more information than a single variable”.
| Eigenvalue | Variance percent | Cumulative variance percent | |
|---|---|---|---|
| PC1 | 3.55 | 44.35 | 44.35 |
| PC2 | 1.44 | 17.94 | 62.29 |
| PC3 | 1.07 | 13.35 | 75.64 |
| PC4 | 0.79 | 9.85 | 85.49 |
| PC5 | 0.57 | 7.07 | 92.56 |
| PC6 | 0.27 | 3.42 | 95.98 |
| PC7 | 0.22 | 2.72 | 98.69 |
| PC8 | 0.10 | 1.31 | 100.00 |
As you can see in the table above they account for about 75,6% of data variability - that’s fine. However in order to make interpretations of the components easier we are going to incorporate 4 of them in our further analysis. In that way almost 85,5% of the variance will be explained.
Let’s have a look now on the PCA loadings so we can think of some resonable interpretations.
| Variable | PC1 | PC2 | PC3 | PC4 | PC5 | PC6 | PC7 | PC8 |
|---|---|---|---|---|---|---|---|---|
| MV_SPD | -0.415 | 0.169 | -0.204 | 0.02 | 0.576 | -0.629 | 0.166 | 0.051 |
| MANA | 0.365 | 0.499 | -0.33 | 0.018 | -0.004 | -0.054 | 0.023 | -0.711 |
| HP_RGN | -0.272 | 0.489 | 0.331 | -0.393 | 0.373 | 0.533 | 0.001 | -0.003 |
| P_ATK | -0.224 | -0.17 | -0.549 | -0.723 | -0.276 | 0.043 | 0.14 | 0.005 |
| P_DFN | -0.393 | 0.316 | 0.033 | 0.333 | -0.483 | 0.071 | 0.628 | 0.031 |
| HP | -0.43 | 0.3 | 0.023 | 0.043 | -0.396 | -0.198 | -0.725 | -0.026 |
| ATK_SPD | -0.318 | -0.212 | -0.529 | 0.452 | 0.252 | 0.518 | -0.164 | -0.101 |
| MANA_RGN | 0.361 | 0.468 | -0.396 | 0.073 | 0 | 0.058 | -0.069 | 0.693 |
The most obvious interpretation has definitely PC2. We can think of it as durability of a character because the loadings’ values by health points and health points regeneration are large and influence PC in one direction.
Next quite resonable interpretation would be physical strength for PC4 because of extend of attack points influence and also becasue of the opposite sign of armor variable.
Readiness to fight would be the label for PC3. Since both signs of loadings by variable mana and mana regeneration are strongly negative, we would expect all magical champions to have very low value of PC3.
As we cannot came up with anything better for PC1 let’s call it for now playability and later on maybe we will be able to review that issue.
If we would include PC5 we would probably call it defensive capability. For more precise labeling we should talk to some gamers with experience and knowledge about the game - maybe someday i will upload it with my recent dicoveries :)
Now as we reduced dimentionality we can proceed to the most exciting part of our analysis - clusters distinguishment. To do so we will implement hierarchical algorithm. First let’s start with computing distances between observation. For that purpose we will use first and second order of Minkowski metrics, i.e. Mannhatan and Euclidean distances responsively.
#hc <- hclust(d.e, method = "ward.D2")